package com.nulldev.util.data.Arrays.arrays;

import java.util.Collection;
import java.util.List;

import com.nulldev.util.data.Variables;
import com.nulldev.util.data.Arrays.arrays.ext.glue.GlueList;
import com.nulldev.util.internal.backport.concurrency9.Lists;
import com.nulldev.util.manage.experiments.Experiments;

public class FastLists {

	private static final boolean USE_CONCURRENT_LISTS = Experiments.get("nullUtil://use-concurrent-lists/").isActive();
	private static final boolean USE_CONCURRENT_LIST_V2 = Experiments.get("nullUtil://use-concurrent-list-v2/").isActive();
	private static final boolean USE_GLUE_LISTS = Experiments.get("nullUtil://use-glue-lists/").isActive();

	public static <E> List<E> list() {
		if (USE_CONCURRENT_LISTS && USE_CONCURRENT_LIST_V2)
			return new ConcurrentList2<E>();
		if (USE_CONCURRENT_LISTS)
			return new ConcurrentList<E>();
		else if (USE_GLUE_LISTS)
			return new GlueList<E>();
		else
			return new FastArrayList<E>(true);
	}

	public static <E> List<E> list(final int size) {
		if (USE_CONCURRENT_LISTS && USE_CONCURRENT_LIST_V2)
			return new ConcurrentList2<E>(size);
		if (USE_CONCURRENT_LISTS)
			return new ConcurrentList<E>(size);
		else if (USE_GLUE_LISTS)
			return new GlueList<E>(size);
		else
			return new FastArrayList<E>(size, true);
	}

	public static <E> List<E> list(final E[] list) {
		Variables.requireNonNull(list, "list");
		return list(Lists.of(list));
	}

	public static <E> List<E> list(final Collection<? extends E> list) {
		Variables.requireNonNull(list, "list");
		if (USE_CONCURRENT_LISTS && USE_CONCURRENT_LIST_V2)
			return new ConcurrentList2<E>(list);
		if (USE_CONCURRENT_LISTS)
			return new ConcurrentList<E>(list);
		else if (USE_GLUE_LISTS)
			return new GlueList<E>(list);
		else
			return new FastArrayList<E>(list, true);
	}
}
